﻿#region Legal Disclaimer
// THIS SOFTWARE IS PROVIDED UNDER THIS LICENSE ON AN “AS IS” BASIS, WITHOUT 
// WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT 
// LIMITATION, WARRANTIES THAT THE COVERED SOFTWARE IS FREE OF DEFECTS, 
// MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE 
// RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED SOFTWARE IS WITH 
// YOU. SHOULD ANY OF THIS SOFTWARE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT 
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY 
// NECESSARY SERVICING, REPAIR OR CORRECTION. NO USE OF THIS SOFTWARE IS 
// AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
// 
// Microsoft Public License (Ms-PL) governs use of this software. If you use the software, 
// you accept this license. If you do not accept the license, do not use the software.
#endregion
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using StructureMap;
using SimplyConfigured.Factories;

namespace SimplyConfigured
{
    /// <summary>
    /// 
    /// </summary>
    public class ConfigurationService
    {
        private readonly IConfigurationFactory _factory;
        private static readonly ConfigurationService _instance = new ConfigurationService();


        /// <summary>
        /// Exposes the list of sources used in the current context.
        /// </summary>
        public static Collection<Type> Sources
        {
            get { return _instance._factory.Sources; }
        }

        /// <summary>
        /// Gets the configuration.
        /// </summary>
        /// <returns></returns>
        public static IConfiguration GetConfiguration()
        {
            return _instance._factory.GetConfiguration(Sources);
        }

        private ConfigurationService()
        {
            try
            {
                _factory = ObjectFactory.GetInstance<IConfigurationFactory>();
            }
            catch (Exception ex)
            {
                Debug.WriteLine("An error ocurred when trying to create the configuration factory.");
                Debug.Write(ex);
            }

            if (_factory == null)
            {
                _factory = new DefaultConfigurationFactory();
            }
        }

        /// <summary>
        /// Gets the configuration.
        /// </summary>
        /// <typeparam name="TSource">The type of the ource.</typeparam>
        /// <exception cref="NullReferenceException"></exception>
        /// <returns></returns>
        public static IConfiguration GetConfiguration<TSource>() where TSource : IConfigurationSource
        {
            try
            {
                var instance = ObjectFactory.GetInstance<TSource>();

                if (instance != null)
                {
                    return instance.Instance;
                }

                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, "Type '{0}' could not be instantiated correctly.",
                                                               typeof (TSource).Name));
            }
            catch (Exception ex)
            {
                Debug.WriteLine("An error ocurred when trying to create the configuration source <TSource>.");
                Debug.Write(ex);

                throw;
            }
        }
    }
}